<template>
  <el-drawer v-model="drawerVisible" :destroy-on-close="true" size="600px" :title="`${drawerProps.title}客户`">
    <el-form ref="ruleFormRef" label-width="100px" label-suffix=" :" :model="localData" label-position="left">
      <!-- 动态生成表单部分 -->
      <template v-for="category in groupedFields" :key="category.name">
        <el-divider content-position="left">{{ category.name }}</el-divider>

        <template v-for="field in category.fields" :key="field.prop">
          <!-- 图片上传字段 -->
          <el-form-item v-if="field.renderType === 'img'" :label="field.label" :prop="field.prop" :rules="getFieldRules(field)">
            <UploadImg
              v-model:image-url="localData[field.prop]"
              @update:image-url="url => updateFieldValue(field.prop, url)"
              :api="uploadImgApi"
              width="135px"
              height="135px"
              :file-size="3"
            >
              <template #empty>
                <el-icon><Avatar /></el-icon>
                <span>请上传{{ field.label }}</span>
              </template>
              <template #tip> {{ field.label }}大小不能超过 3M </template>
            </UploadImg>
          </el-form-item>

          <!-- 字符串数组字段（上下游关系） -->
          <el-form-item v-else-if="field.renderType === 'strArr'" :label="field.label" :prop="field.prop">
            <div class="tag-input-container">
              <div class="tags" v-if="localData[field.prop]">
                <el-tag
                  v-for="(item, index) in getArrayFromString(localData[field.prop])"
                  :key="index"
                  closable
                  :disable-transitions="false"
                  @close="removeTag(field.prop, index)"
                >
                  {{ item }}
                </el-tag>
              </div>

              <el-input
                v-model="tagInputs[field.prop]"
                :ref="setInputRef(field.prop)"
                size="small"
                class="input-new-tag"
                :placeholder="field.placeholderTemplate || '请输入'"
                @keyup.enter="addTag(field.prop)"
                @blur="addTag(field.prop)"
              />
            </div>
          </el-form-item>

          <!-- 对象数组字段（联系人） -->
          <el-form-item v-else-if="field.renderType === 'objArr'" :label="field.label" :prop="field.prop">
            <div v-for="(item, index) in localData[field.prop]" :key="index" class="contact-item">
              <div class="contact-header">
                <el-button type="danger" size="small" :icon="Delete" circle @click="removeItem(field.prop, index)" />
              </div>

              <template v-for="subField in field.formConfig" :key="subField.key">
                <el-form-item
                  :label="subField.label"
                  :prop="`${field.prop}[${index}].${subField.key}`"
                  :rules="getSubFieldRules(subField)"
                >
                  <el-input
                    v-model="item[subField.key]"
                    :placeholder="subField.placeholderTemplate || '请输入'"
                    clearable
                    :type="subField.inputType"
                    :rows="subField.inputType === 'text' ? 2 : subField.inputType === 'textarea' ? 3 : undefined"
                  />
                </el-form-item>
              </template>
            </div>

            <el-button type="primary" :icon="Plus" @click="addItem(field)"> 添加{{ field.label }} </el-button>
          </el-form-item>

          <!-- 数字输入字段 -->
          <el-form-item
            v-else-if="field.renderType === 'number'"
            :label="field.label"
            :rules="getFieldRules(field)"
            :prop="field.prop"
          >
            <el-input-number v-model="localData[field.prop]" :min="1">
              <template #suffix>
                <span>{{ field.unit }}</span>
              </template>
            </el-input-number>
          </el-form-item>

          <!-- 文本域字段 -->
          <el-form-item
            v-else-if="field.renderType === 'textarea'"
            :label="field.label"
            :rules="getFieldRules(field)"
            :prop="field.prop"
          >
            <el-input type="textarea" v-model="localData[field.prop]" :placeholder="field.placeholderTemplate || '请输入'" />
          </el-form-item>

          <!-- 默认文本输入字段 -->
          <el-form-item v-else :label="field.label" :prop="field.prop" :rules="getFieldRules(field)">
            <el-input v-model="localData[field.prop]" :placeholder="field.placeholderTemplate || '请输入'" clearable />
          </el-form-item>
        </template>
      </template>
    </el-form>

    <template #footer>
      <el-button @click="drawerVisible = false">取消</el-button>
      <el-button type="primary" @click="handleSubmit">确定</el-button>
    </template>
  </el-drawer>
</template>

<script setup lang="ts">
import { ref, reactive, computed, nextTick } from "vue";
import { ElMessage, FormInstance } from "element-plus";
import { Delete, Plus, Avatar } from "@element-plus/icons-vue";
import { Customer, ColumnForm, RuleConfig, FieldConfig } from "@/api/interface";
import UploadImg from "@/components/Upload/Img.vue";

interface DrawerProps {
  title: string;
  row: Partial<Customer.CustomerInfo>;
  api?: (params: any) => Promise<any>;
  columns: ColumnForm<Customer.CustomerInfo>[];
  getTableList?: () => void;
}

const drawerVisible = ref(false);
const drawerProps = ref<DrawerProps>({
  title: "",
  row: {},
  columns: []
});

// 本地数据副本
const localData = ref<Partial<Customer.CustomerInfo>>({
  status: 1,
  contacts: [],
  upstreamSuppliers: "",
  downstreamCustomers: ""
});

// 标签输入框的值和引用
const tagInputs = reactive<Record<string, string>>({});
const inputRefs = reactive<Record<string, any>>({});

// 根据字段配置分组
const groupedFields = computed(() => {
  const fields = drawerProps.value.columns.filter(field => field.isShow && field.prop !== "operation");
  const categories = new Map<string, FieldConfig[]>();

  fields.forEach(field => {
    if (!categories.has(field.category)) {
      categories.set(field.category, []);
    }
    categories.get(field.category)?.push(field);
  });

  return Array.from(categories.entries()).map(([name, fields]) => ({
    name,
    fields
  }));
});

// 获取字段验证规则
const getFieldRules = (field: FieldConfig) => {
  if (!field.required) return [];

  return [{ required: true, message: `请输入${field.label}`, trigger: "blur" }];
};

// 获取子字段验证规则
const getSubFieldRules = (subField: any) => {
  if (!subField.required) return [];

  const rules: RuleConfig[] = [{ required: true, message: `请输入${subField.label}`, trigger: "blur" }];

  if (subField.key === "phone") {
    rules.push({
      pattern: /^1[3-9]\d{9}$/,
      message: "请输入正确的手机号码",
      trigger: "blur"
    });
  }

  return rules;
};

// 深拷贝函数
const deepClone = <T,>(obj: T): T => {
  if (obj === null || typeof obj !== "object") {
    return obj;
  }

  if (Array.isArray(obj)) {
    return obj.map(item => deepClone(item)) as unknown as T;
  }

  const cloned: Record<string, any> = {};
  for (const key in obj) {
    if (Object.prototype.hasOwnProperty.call(obj, key)) {
      cloned[key] = deepClone(obj[key]);
    }
  }
  return cloned as T;
};

// 图片上传API
const uploadImgApi = (formData: FormData) => {
  const file = formData.get("file") as File;
  return new Promise((resolve, reject) => {
    if (!file) {
      reject(new Error("没有文件选择"));
      return;
    }
    const reader = new FileReader();
    reader.onload = () => {
      resolve({ fileUrl: reader.result as string });
    };
    reader.onerror = () => {
      reject(new Error("加载图片失败"));
    };
    reader.readAsDataURL(file);
  });
};

// 更新字段值
const updateFieldValue = (prop: string, value: any) => {
  localData.value[prop] = value;
};

// 设置输入框引用
const setInputRef = (prop: string) => (el: any) => {
  inputRefs[prop] = el;
};

// 从字符串获取数组
const getArrayFromString = (str: string) => {
  return str ? str.split(",").filter(item => item.trim() !== "") : [];
};

// 添加标签
const addTag = (prop: string) => {
  const inputValue = tagInputs[prop];
  if (!inputValue) return;

  let arr = getArrayFromString(localData.value[prop] as string);
  if (!arr.includes(inputValue)) {
    arr.push(inputValue);
    localData.value[prop] = arr.join(",");
    tagInputs[prop] = "";
    nextTick(() => {
      inputRefs[prop]?.focus();
    });
  }
};

// 移除标签
const removeTag = (prop: string, index: number) => {
  let arr = getArrayFromString(localData.value[prop] as string);
  arr.splice(index, 1);
  localData.value[prop] = arr.length > 0 ? arr.join(",") : "";
};

// 添加项目（联系人等）
const addItem = (field: FieldConfig) => {
  if (!localData.value[field.prop]) {
    localData.value[field.prop] = [];
  }

  const newItem: Record<string, any> = {};
  if (field.formConfig) {
    field.formConfig.forEach(subField => {
      newItem[subField.key] = "";
    });
  }

  (localData.value[field.prop] as any[]).push(newItem);
};

// 移除项目
const removeItem = (prop: string, index: number) => {
  (localData.value[prop] as any[]).splice(index, 1);
};

// 接收父组件参数
const acceptParams = (params: DrawerProps) => {
  drawerProps.value = params;
  localData.value = {
    status: 1,
    ...deepClone(params.row)
  };

  // 初始化标签输入框
  tagInputs.upstreamSuppliers = "";
  tagInputs.downstreamCustomers = "";

  drawerVisible.value = true;
};

// 提交表单
const ruleFormRef = ref<FormInstance>();
const handleSubmit = () => {
  ruleFormRef.value?.validate(async valid => {
    if (!valid) return;

    // 检查联系人手机号是否重复
    if (localData.value.contacts) {
      const phoneMap = new Map();
      const duplicates: string[] = [];

      for (const contact of localData.value.contacts) {
        if (phoneMap.has(contact.phone)) {
          duplicates.push(contact.phone);
        } else {
          phoneMap.set(contact.phone, true);
        }
      }

      if (duplicates.length > 0) {
        ElMessage.error(`以下手机号重复: ${duplicates.join(", ")}`);
        return;
      }
    }

    try {
      await drawerProps.value.api?.(localData.value);
      ElMessage.success(`${drawerProps.value.title}公司成功！`);
      drawerProps.value.getTableList?.();
      drawerVisible.value = false;
    } catch (error) {
      console.error(error);
    }
  });
};

defineExpose({
  acceptParams
});
</script>

<style scoped>
.contact-item {
  width: 100%;
  padding: 16px;
  margin-bottom: 20px;
  background-color: #ffffff;
}
.contact-header {
  display: flex;
  flex-direction: row-reverse;
  margin-bottom: 10px;
}
.tag-input-container {
  display: flex;
  flex-direction: column;
  gap: 8px;
  width: 100%;
}
.tags {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
}
.input-new-tag {
  width: 100%;
}
.el-divider {
  margin: 24px 0;
}
.el-form-item {
  margin-bottom: 18px;
}
.el-form-item:last-child {
  margin-bottom: 0;
}
</style>
